//===================================================================
// 项目名 : Hbt.Infrastructure
// 文件名 : HbtSignalRCollectionExtensions.cs
// 创建者 : Lean365
// 创建时间: 2024-03-07 16:30
// 版本号 : V0.0.1
// 描述   : SignalR扩展类
//===================================================================

using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Hbt.Domain.IServices.SignalR;
using Hbt.Infrastructure.SignalR;
using Hbt.Infrastructure.SignalR.Cache;
using Hbt.Infrastructure.SignalR.Notification;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using System.Text.Json;
using LogLevel = Microsoft.Extensions.Logging.LogLevel;
using Hbt.Common.Options;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http.Connections;

namespace Hbt.Infrastructure.Extensions
{
    /// <summary>
    /// SignalR扩展类
    /// </summary>
    public static class HbtSignalRCollectionExtensions
    {
        /// <summary>
        /// 添加SignalR服务 - 统一注册所有SignalR相关服务
        /// </summary>
        public static IServiceCollection AddHbtSignalR(this IServiceCollection services, IConfiguration configuration)
        {
            // 获取SignalR配置
            var signalRConfig = configuration.GetSection("SignalR").Get<SignalRConfig>();

            // 配置SignalR日志
            services.AddLogging(logging =>
            {
                logging.AddFilter("Microsoft.AspNetCore.SignalR", 
                    signalRConfig.EnableDetailedErrors ? LogLevel.Debug : LogLevel.Information);
                logging.AddFilter("Microsoft.AspNetCore.Http.Connections", 
                    signalRConfig.EnableDetailedErrors ? LogLevel.Debug : LogLevel.Information);
            });

            // 配置SignalR
            services.AddSignalR(options =>
            {
                // 基本设置
                options.EnableDetailedErrors = signalRConfig.EnableDetailedErrors;
                options.MaximumReceiveMessageSize = signalRConfig.MaximumReceiveMessageSize;
                options.HandshakeTimeout = TimeSpan.FromSeconds(signalRConfig.HandshakeTimeout);
                options.KeepAliveInterval = TimeSpan.FromSeconds(signalRConfig.KeepAliveInterval);
                options.ClientTimeoutInterval = TimeSpan.FromSeconds(signalRConfig.ClientTimeoutInterval);
                options.StreamBufferCapacity = signalRConfig.StreamBufferCapacity;
            })
            .AddHubOptions<HbtSignalRHub>(options =>
            {
                options.EnableDetailedErrors = signalRConfig.EnableDetailedErrors;
                options.MaximumReceiveMessageSize = signalRConfig.MaximumReceiveMessageSize;
                options.HandshakeTimeout = TimeSpan.FromSeconds(signalRConfig.HandshakeTimeout);
                options.KeepAliveInterval = TimeSpan.FromSeconds(signalRConfig.KeepAliveInterval);
                options.ClientTimeoutInterval = TimeSpan.FromSeconds(signalRConfig.ClientTimeoutInterval);
            })
            .AddJsonProtocol(options =>
            {
                options.PayloadSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
                options.PayloadSerializerOptions.WriteIndented = false;
            });

            // 注册所有 SignalR 相关服务
            // 注意：所有 SignalR 相关服务都在这里统一注册，包括：
            // 1. Infrastructure 层服务：连接服务、Hub、通知服务
            // 2. Application 层服务：在线用户服务、在线消息服务
            services.AddScoped<IHbtSignalRConnectionService, HbtSignalRConnectionService>(); // SignalR连接服务
            services.AddScoped<IHbtSignalRHub, HbtSignalRHub>();
            services.AddScoped<IHbtSignalRNotificationService, HbtSignalRNotificationService>(); // 通知服务
            services.AddScoped<IHbtSignalRMessageService, HbtSignalRMessageService>(); // 在线消息服务
            services.AddScoped<IHbtSignalROnlineService, HbtSignalROnlineService>(); // 在线用户服务
            services.AddScoped<IHbtSignalRClient>(sp =>
            {
                var hubContext = sp.GetRequiredService<IHubContext<HbtSignalRHub, IHbtSignalRClient>>();
                return hubContext.Clients.All;
            });

            // 配置 SignalR 缓存选项
            services.Configure<HbtSignalRCacheOptions>(
                configuration.GetSection("SignalRCache"));

            // JWT 认证配置已移至 Program.cs 中统一处理，避免重复配置

            return services;
        }

        /// <summary>
        /// 使用SignalR
        /// </summary>
        public static IApplicationBuilder UseHbtSignalR(this IApplicationBuilder app)
        {
            var configuration = app.ApplicationServices.GetRequiredService<IConfiguration>();
            var signalRConfig = configuration.GetSection("SignalR").Get<SignalRConfig>();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapHub<HbtSignalRHub>("/signalr/hbthub", options =>
                {
                    options.CloseOnAuthenticationExpiration = signalRConfig.Authentication.RequireAuthentication;
                    options.ApplicationMaxBufferSize = signalRConfig.MaximumReceiveMessageSize;
                    options.TransportMaxBufferSize = signalRConfig.MaximumReceiveMessageSize;
                });
            });

            return app;
        }
    }
}